package cn.js189.uqc.common;

import cn.hutool.extra.spring.SpringUtil;
import cn.js189.common.constants.Constants;
import cn.js189.uqc.mapper.ChannelInfoMapper;
import cn.js189.uqc.redis.RedisOperation;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 江苏电信O3资源中心，生成请求报文基础类
 * 
 * @author Mid
 */
public abstract class OSS3RequestParamBase {
	// 日志组件
	private static final Logger LOGGER = LoggerFactory.getLogger(OSS3RequestParamBase.class);

	// appKey
	public static final String OSS3_TCP_CONT_APP_KEY = "JS00000001";
	// 时间格式yyyyMMddHHmmss
	private static final String OSS3_TCP_CONT_DATE_FORMAT = "yyyyMMddHHmmss";
	// tcpCont交易流水长度
	private static final int OSS3_TCP_CONT_TRANS_ID_LENGTH = 18;
	// tcpCont交易流水中随机数的长度
	private static final int OSS3_TCP_CONT_TRANS_ID_RANDOM_LENGTH = 4;
	// 10,000,000,000
	private static final long OSS3_TCP_CONT_TEN_THOUSAND = 10000L;

	// 当前时间，格式yyyyMMddHHmmss
	private String nowString;

	/**
	 * 生成请求参数
	 */
	public JSONObject generateContractRoot() {
		JSONObject tcpCont = generateTcpCont();
		if (null == tcpCont) {
			LOGGER.error("generate tcpCont failure");
			return null;
		}

		JSONObject svcCont = generateSvcCont();
		if (null == svcCont) {
			LOGGER.error("generate svcCont failure");
			return null;
		}

		JSONObject contractRoot = new JSONObject();
		contractRoot.put("TcpCont", tcpCont);
		contractRoot.put("SvcCont", svcCont);

		JSONObject contractRootJSON = new JSONObject();
		contractRootJSON.put("ContractRoot", contractRoot);
		return contractRootJSON;
	}

	/**
	 * 生成 tcpCont 会话控制信息
	 */
	protected abstract JSONObject generateTcpCont();

	/**
	 * 生成 svcCont 业务内容信息
	 */
	protected abstract JSONObject generateSvcCont();

	/**
	 * 生成 tcpCont 会话控制信息
	 * 
	 * @param appKey:调用方用户名，见主数据
	 * @param svcCode:提供的API接口名称
	 * @param transactionId:唯一交易流水号
	 * @return
	 */
	protected JSONObject generateTcpCont(String appKey, String svcCode, String transactionId) {
		boolean isBlankFlag = StringUtils.isBlank(appKey) || StringUtils.isBlank(svcCode);
		if (isBlankFlag) {
			LOGGER.error("appKey is blank or svcCode is blank, appKey:{}, svcCode:{}", appKey, svcCode);
			return null;
		}

		SimpleDateFormat sdf = new SimpleDateFormat(OSS3_TCP_CONT_DATE_FORMAT);
		nowString = sdf.format(new Date());

		if (StringUtils.isBlank(transactionId)) {
			transactionId = generateTransId();
		} else {
			if (transactionId.length() != OSS3_TCP_CONT_TRANS_ID_LENGTH) {
				LOGGER.error("transactionId is invalid, transactionId:{}", transactionId);
				return null;
			}
		}

		JSONObject tcpCont = new JSONObject();
		tcpCont.put("TransactionID", transactionId);
		tcpCont.put("AppKey", appKey);
		tcpCont.put("Method", svcCode);
		tcpCont.put("ReqTime", nowString);
		
		//先从redis获取sign,没有查库
		RedisOperation redisOperation = (RedisOperation) SpringUtil.getBean("redisOperation");
		String eopSign = redisOperation.getForString(Constants.EOP_SIGN);
		if(StringUtils.isBlank(eopSign)){
			ChannelInfoMapper channelInfoMapper = (ChannelInfoMapper) SpringUtil.getBean("channelInfoMapper");
			eopSign = channelInfoMapper.getSignByChannelId("EOP");
		}
		tcpCont.put("sign", eopSign);
		return tcpCont;
	}

	/**
	 * 生成 tcpCont 下的交易流水
	 * 
	 * @return
	 */
	private String generateTransId() {
		long random = (long) (Math.random() * OSS3_TCP_CONT_TEN_THOUSAND);
		StringBuilder sb = new StringBuilder();
		sb.append(nowString);
		String randomStr = String.valueOf(random);
		int zeroPaddingLen = OSS3_TCP_CONT_TRANS_ID_RANDOM_LENGTH - randomStr.length();
		if (zeroPaddingLen > 0) {
			for (int i = 0; i < zeroPaddingLen; i++)
				sb.append("0");
		}
		sb.append(randomStr);
		return sb.toString();
	}

}
